from django.shortcuts import render
from django.contrib.auth.decorators import login_required
from django.template.context_processors import csrf
from django.http import HttpResponseRedirect
from django.contrib.auth.models import User, Group
from .models import Appointment
from datetime import datetime
from django.utils import timezone
from home.context_processors import hasGroup
from case.models import case
from django.contrib import messages
import datetime
import queue
import collections
import threading
# Create your views here.


class wait_array(object):
    array = {}

    def array_create(self, id, queue):
        wait_array.array[id] = queue

    def get(self):
        return wait_array.array


class BookingFormQueue(object):
    def __init__(self, queue_id):
        self.queue = []
        self.queue_id = queue_id

    # 设置排序权重，-等待时间*某种权重（专家号？），权重越小优先度越高

    # 新增挂号单到队列，在time_out秒内其他增添请求会被阻塞
    def add_new_bookingform(self, appointment):

        self.queue.append(appointment)
        self.queue.sort(key=lambda x: x.appointment_time)

    # 从队列中拿出优先度最高的[优先度，挂号单id]，阻塞time_out秒#
    def pop_bookingform(self):
        if len(self.queue) > 0:
            bk_form_section = self.queue.pop(0)
            return bk_form_section
        else:
            print("warning: the queue is empty")

    def get_wait_no(self, username):
        if len(self.queue) > 0:
            for i in range(0, len(self.queue)):
                if username == self.queue[i].patient.username:
                    return i
        return -1


# CREATE
@login_required
def book(request):
    user = request.user
    if hasGroup(user, 'receptionist') or hasGroup(user, 'doctor'):
        c = {}
        c.update(csrf(request))
        c['patients'] = User.objects.filter(groups__name='patient')
        c['doctors'] = User.objects.filter(groups__name='doctor')
        doctor_name = request.POST.get('doctor_name', '')
        patient_name= request.POST.get('patient_name', '')
        if patient_name == '' and doctor_name=='':
            c['patient_list'] = User.objects.filter(groups__name='patient')
            c['doctors_list'] = User.objects.filter(groups__name='doctor')
            return render(request, 'appointments/book_appointment.html', c)
        elif patient_name == '' and doctor_name!='':
            patient_list_new = User.objects.filter(groups__name='patient')
            doctor_list_new=User.objects.filter(groups__name='doctor',username__contains=doctor_name)
            c['patient_list'] = patient_list_new
            c['doctors_list']=doctor_list_new
            return render(request, 'appointments/book_appointment.html', c)
        elif patient_name != '' and doctor_name=='':
            patient_list_new = User.objects.filter(groups__name='patient',username__contains=patient_name)
            doctor_list_new = User.objects.filter(groups__name='doctor')
            c['patient_list'] = patient_list_new
            c['doctors_list'] = doctor_list_new
            return render(request, 'appointments/book_appointment.html', c)
        else:
            patient_list_new = User.objects.filter(groups__name='patient', username__contains=patient_name)
            doctor_list_new = User.objects.filter(groups__name='doctor', username__contains=doctor_name)
            c['patient_list'] = patient_list_new
            c['doctors_list']=doctor_list_new
            return render(request, 'appointments/book_appointment.html', c)
    else:
        messages.add_message(request, messages.WARNING, 'Access Denied.')
        return HttpResponseRedirect('/home')


@login_required
def doBook(request):
    print("dobook")
    user = request.user
    if hasGroup(user, 'receptionist') or hasGroup(user, 'doctor'):
        patient = User.objects.get(username=request.POST.get('patient', ''))
        doctor = User.objects.get(username=request.POST.get('doctor', ''))
        description = request.POST.get('description', '')
        print(description)
        #c = case.objects.get(pk=int(request.POST.get('case', '')))
        #print(c)
        appointment_time = request.POST.get(
            'appointment_date')+' '+request.POST.get('appointment_time')
        #l = appointment_time.replace('T', '-').replace(':', '-').split('-')

        appointment = Appointment( patient=patient, doctor=doctor,
                                  appointment_time=appointment_time, appointment_description=description)
        appointment.save()
        messages.add_message(request, messages.INFO,
                             'Appointment Successfully Booked')
    else:
        messages.add_message(request, messages.WARNING, 'Access Denied.')
    return HttpResponseRedirect('/appointments/')


# RETRIEVE
@login_required
def view(request):
    wa = wait_array()
    c = {}
    user = request.user
    if hasGroup(user, 'receptionist'):
        c['isReceptionist'] = True
        c['appointments'] = Appointment.objects.filter(
            appointment_time__gte=timezone.now(),appointment_done=0).order_by('appointment_time')
    elif hasGroup(user, 'patient'):
        c['appointments'] = Appointment.objects.filter(
            patient=user, appointment_time__gte=timezone.now(),appointment_done=0).order_by('appointment_time')
    elif hasGroup(user, 'doctor'):
        if user.username not in wa.array.keys():
            print("d")
            queue_temp = BookingFormQueue(user.username)
            appointments = Appointment.objects.filter(
                doctor=user, appointment_time__gte=timezone.now(),appointment_done=0).order_by('appointment_time')
            for appointment in appointments:
                queue_temp.add_new_bookingform(appointment)
            wa.array_create(user.username, queue_temp)
            queue_d = queue_temp
        else:
            queue_d = wa.array[str(user.username)]

        c['appointments'] = queue_d.queue
        print(len(queue_d.queue))

    else:
        messages.add_message(request, messages.WARNING, 'Access Denied.')
        return HttpResponseRedirect('/home')
    return render(request, 'appointments/view_all.html', c)


# UPDATE
@login_required
def changeAppointment(request, id):
    user = request.user
    if hasGroup(user, 'receptionist'):
        c = {'appointment': Appointment.objects.get(pk=id)}
        c['doctors'] = User.objects.filter(groups__name='doctor')
        c.update(csrf(request))
        return render(request, 'appointments/change.html', c)
    messages.add_message(request, messages.WARNING, 'Access Denied.')
    return HttpResponseRedirect('/home')


@login_required
def doChange(request):
    user = request.user
    if hasGroup(user, 'receptionist'):
        appointment = Appointment.objects.get(pk=int(request.POST.get('id')))
        appointment.doctor = User.objects.get(
            username=request.POST.get('doctor', ''))
        appointment_time = request.POST.get(
            'appointment_date')+'T'+request.POST.get('appointment_time')
        appointment_time = datetime(
            *[int(v) for v in appointment_time.replace('T', '-').replace(':', '-').split('-')])
        appointment.appointment_time = appointment_time
        appointment.receptionist = request.user
        appointment.save()
    messages.add_message(request, messages.INFO,
                         'Appointment Successfully Changed')
    return HttpResponseRedirect('/appointments/')

# DELETE


def delete(request, id):
    user = request.user
    if hasGroup(user, 'receptionist'):
        Appointment.objects.get(id=id).delete()
        messages.add_message(request, messages.INFO,
                             'Appointment Successfully Deleted')
    else:
        messages.add_message(request, messages.WARNING, 'Access Denied.')
    return HttpResponseRedirect('/appointments/')
